package ai

import (
	"reflect"
	"time"
)

type TypeRole int
type TypeShape int
type TypeDirection int
type TypeShapeCache map[TypeRole]map[TypeDirection]*TypeRepo[TypeShape]
type TypePointCache map[TypeRole]map[TypeShape]map[int]bool
type TypeScore map[TypeRole]*TypeRepo[int]

type TypeHistory struct {
	x    int
	y    int
	role TypeRole
}

type TypeEvaluateCache struct {
	role  TypeRole
	score int
}

type TypeValuableMoveCache struct {
	role      TypeRole
	moves     []Point
	depth     int
	onlyThree bool
	onlyFour  bool
}

// ShapeEnum 可取的形状
type ShapeEnum struct {
	FIVE        TypeShape //11111
	FOUR        TypeShape //011110
	FOUR_FOUR   TypeShape
	FOUR_THREE  TypeShape
	THREE_THREE TypeShape
	BLOCK_FOUR  TypeShape //10111|11011|011112
	THREE       TypeShape //011100|011010
	BLOCK_THREE TypeShape //211100|211010|210110|11001|10101|2011102
	TWO_TWO     TypeShape
	TWO         TypeShape //001100|011000|000110|010100|001010
	BLOCK_TWO   TypeShape
	ONE         TypeShape
	BLOCK_ONE   TypeShape
	NONE        TypeShape
}
type TypePerformance struct {
	updateTime    time.Duration
	getPointsTime time.Duration
}

type Point struct {
	x int
	y int
}

type TypeRepo[T TypeRole | int | uint64 | TypeShape] struct {
	// 存储二维数组，主要解决row,col-->x,y的映射关系
	repo [][]T
	size int
}

func NewTypeRepo[T TypeRole | int | uint64 | TypeShape](size int) *TypeRepo[T] {
	repo := make([][]T, size)
	for i := range repo {
		repo[i] = make([]T, size)
	}
	return &TypeRepo[T]{
		repo: repo,
		size: size,
	}
}
func (tr *TypeRepo[T]) Put(x, y int, val T) {
	tr.repo[y][x] = val
}
func (tr *TypeRepo[T]) Get(x, y int) T {
	return tr.repo[y][x]
}

func (tr *TypeRepo[T]) GetSliceX(xStart, xEnd, y int) []T {
	return tr.repo[y][max(0, xStart):min(tr.size, xEnd+1)]
}
func (tr *TypeRepo[T]) GetSliceY(x, yStart, yEnd int) []T {
	return tr.repo[max(0, yStart):min(tr.size, yEnd+1)][x]
}
func (tr *TypeRepo[T]) GetSliceXY(xStart, xEnd, yStart, sign int) []T {
	arr := make([]T, xEnd-xStart+1)
	for x := xStart; x <= xEnd; x++ {
		arr = append(arr, tr.repo[yStart+sign*(x-xStart)][x])
	}
	return arr
}

type Vector Point

type ChessEnum struct {
	WHITE    TypeRole
	BLACK    TypeRole
	EMPTY    TypeRole
	OBSTACLE TypeRole
}

type PieceCount struct {
	selfCount         int // 属于role的棋子个数
	noEmptySelfCount  int // 没有空位的role棋子个数
	oneEmptySelfCount int // 一个空位的role棋子个数
	innerEmptyCount   int // 棋子中间的内部空位
	sideEmptyCount    int // 边上的空位
}

var Chess = &ChessEnum{
	BLACK:    BLACK,
	WHITE:    WHITE,
	EMPTY:    EMPTY,
	OBSTACLE: OBSTACLE,
}
var Roles = []TypeRole{Chess.BLACK, Chess.WHITE}
var DirectionVec = []Vector{{1, 0}, {0, 1}, {1, -1}, {1, 1}}
var DirectionEnum = []TypeDirection{HORIZONTAL, VERTICAL, DIAGONAL, ANTI_DIAGONAL}
var Shapes = &ShapeEnum{
	FIVE:        5,
	FOUR:        4,
	FOUR_FOUR:   44,
	FOUR_THREE:  43,
	THREE_THREE: 33,
	BLOCK_FOUR:  40,
	THREE:       3,
	BLOCK_THREE: 30,
	TWO_TWO:     22,
	TWO:         2,
	BLOCK_TWO:   20,
	ONE:         1,
	BLOCK_ONE:   10,
	NONE:        0,
}
var ShapeFields []TypeShape

func init() {
	// 初始化 ShapeFields
	ShapeFields = make([]TypeShape, 0)
	v := reflect.ValueOf(*Shapes)
	for i := 0; i < v.NumField(); i++ {
		ShapeFields = append(ShapeFields, v.Field(i).Interface().(TypeShape))
	}
}
